home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / Archive / PP_v1.4 / Source.LhA / Source / res.c < prev   
C/C++ Source or Header  |  1991-12-21  |  2KB  |  95 lines

  1. /* Res.C - Autodetach code for Manx in C
  2. **
  3. ** Thanks to Eddy Carrol for his groundwork in assembler. I rewrote it
  4. ** in C 'cause assembly isn't really my favourite language..
  5. ** (Eddy's code also contains a few potential bugs..)
  6. **
  7. ** Eddy writes good documentation, so get "CPUBlit" from Fred Fish and
  8. ** study the source code and docs there..
  9. **
  10. ** Synopsis for res:
  11. **
  12. ** struct Task *pid = res(char *name, int pri, int (*kickoff)(), int stack)
  13. **
  14. ** kickoff() will be spawned as a completely selfcontained process. Caller's
  15. ** code will not be UnLoadSeg'ed until kickoff() terminates (exit() is a no-no
  16. ** in kickoff(), use return(doscode)!)
  17. **
  18. ** There's more, so read Eddy's docs!
  19. **
  20. ** This file is part of the Powerpacker Patcher project.
  21. ** Copyright 1991, Michael Berg. (Thanx Eddy!)
  22. */
  23.  
  24. #include <pragmas.h>
  25. #include <exec/types.h>
  26. #include <libraries/dos.h>
  27. #include <libraries/dosextens.h>
  28. #include <exec/memory.h>
  29.  
  30. struct FakeSeg
  31. {
  32.     ULONG segsize;
  33.     ULONG segptr;
  34.     UWORD op_moveim_a4;    ULONG reg_a4;
  35.     UWORD op_jsrabs;    int (*func)();
  36.     UWORD op_moveim_a6;    ULONG reg_a6;
  37.     UWORD op_moveim_d1;    ULONG reg_d1;
  38.     UWORD op_jmpindir_a6;    UWORD lvo_unloadseg;
  39. };
  40.  
  41. #define SEGSIZE    sizeof(struct FakeSeg)
  42.  
  43. typedef struct Process PROCESS;
  44.  
  45. extern struct DOSBase *DOSBase;
  46.  
  47. /* Doesn't Manx have another way to get at a register..? */
  48. fetch_a4()
  49. {
  50. #asm
  51.     move.l    a4,d0
  52. #endasm
  53. }
  54.  
  55. /* Well, here it is! */
  56. struct Task *res(char *name,int pri,int (*fptr)(),int stacksize)
  57. {
  58.     register struct FakeSeg *fs;
  59.  
  60.     if (fs = (struct FakeSeg *)AllocMem(SEGSIZE,MEMF_PUBLIC))
  61.     {
  62.         register PROCESS *ThatsMe = (PROCESS *)FindTask(0);
  63.         BPTR ourseg,CLI;
  64.         struct Task *created;
  65.  
  66.         ourseg = ThatsMe->pr_CLI;
  67.         CLI = ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module;
  68.         ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module = (BPTR)0;
  69.  
  70.         fs->segptr  = (ULONG)CLI;
  71.         fs->segsize = SEGSIZE;
  72.  
  73.         fs->op_moveim_a4 = 0x287C;
  74.         fs->reg_a4     = fetch_a4();
  75.         fs->op_jsrabs     = 0x4EB9;
  76.         fs->func     = fptr;
  77.         fs->op_moveim_a6 = 0x2C7C;
  78.         fs->reg_a6       = (ULONG)DOSBase;
  79.         fs->op_moveim_d1 = 0x223C;
  80.         fs->reg_d1     = ((ULONG)(&fs->segptr)) >> 2;
  81.         fs->op_jmpindir_a6 = 0x4EEE;
  82.         fs->lvo_unloadseg  = 0xFF64;
  83.  
  84.         if (created = (struct Task *)CreateProc(name,pri,fs->reg_d1,stacksize))
  85.             return(created);
  86.         else
  87.         {
  88.             ((struct CommandLineInterface *)BADDR(ourseg))->cli_Module = CLI;
  89.             FreeMem(fs,SEGSIZE);
  90.         }
  91.     }
  92.  
  93.     return(NULL);
  94. }
  95.